﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO.Ports;
using System.IO;
using System.Windows.Forms;
using System.Management;

namespace Pulsar
{
    public class SerialPortExcpetion : Exception
    {
    }

    public class PulsarSerialPort : PulsarTagger
    {
        private SerialPort comport = new SerialPort();

        public void Open()
        {
            bool error = false;

            // If the port is open, close it.
            if (comport.IsOpen) comport.Close();
            else
            {
                // Set the port's settings
                comport.BaudRate = PulsarGlobalOptions.ComPortBaudRate;//required by arduino tagger 115200
                comport.DataBits = 8;//int.Parse(cmbDataBits.Text);
                comport.StopBits = (StopBits)Enum.Parse(typeof(StopBits), "One" /*cmbStopBits.Text*/);
                comport.Parity = (Parity)Enum.Parse(typeof(Parity), "None"/*cmbParity.Text*/);
                comport.PortName = PulsarGlobalOptions.ComPortName;

                try
                {
                    // Open the port
                    comport.Open();
                }
                catch (UnauthorizedAccessException) { error = true; }
                catch (IOException) { error = true; }
                catch (ArgumentException) { error = true; }

                if (error)
                {
                    //MessageBox.Show("Could not open the COM port.  Most likely it is already in use, has been removed, or is unavailable.", "COM Port Unavalible", MessageBoxButtons.OK, MessageBoxIcon.Stop);
                    throw new SerialPortExcpetion();
                }
                else
                {
                    // Show the initial pin states
                    //UpdatePinState();
                    //chkDTR.Checked = comport.DtrEnable;
                    //chkRTS.Checked = comport.RtsEnable;
                }
            }
        }

        public void Write(int value) //Hex: 00,01,02,03 .. FF
        {

            byte[] data = {(byte)Convert.ToByte(value)};

            // Send a single byte to the port (as in the port parallel case)
            comport.Write(data, 0, 1);
        }

        public void Close()
        {
            if (comport.IsOpen) comport.Close();
        }

        public static string[] GetUSBCOMDevices()
        {
            List<string> list = new List<string>();

            try
            {
                ManagementObjectSearcher searcher2 = new ManagementObjectSearcher("SELECT * FROM Win32_PnPEntity");
                foreach (ManagementObject mo2 in searcher2.Get())
                {
                    string name = mo2["Name"].ToString();
                    string service = (mo2["Service"] == null) ? "" : mo2["Service"].ToString();
                    // Name will have a substring like "(COM12)" in it.
                    if (name.Contains("(COM") && service.ToLower().Contains("usbser"))
                    {
                        int start = name.IndexOf("(COM") + 1;
                        if (start >= 0)
                        {
                            int end = name.IndexOf(")", start + 3);
                            String cname = name.Substring(start, end - start);
                            list.Add(cname);
                        }

                    }
                }
                // remove duplicates, sort alphabetically and convert to array
                string[] usbDevices = list.Distinct().OrderBy(s => s).ToArray();
                return usbDevices;
            }
            catch (Exception ex)
            {
                return list.ToArray();
            }
        }

        public static string[] GetAllExisting()
        {
            return SerialPort.GetPortNames();
        }
    }
}
